package com.wuhongyu.tree;

public class BSTree<E extends Comparable<E>> {

    private class Node {
        E e;
        Node left;
        Node right;

        public Node() {}

        public Node(E e) {
            this.e = e;
            this.left = null;
            this.right = null;
        }

        public Node(E e, Node left, Node right) {
            this.e = e;
            this.left = left;
            this.right = right;
        }
    }

    private Node root;
    private int size;

    public BSTree() {
        this.root = null;
        this.size = 0;
    }

    public int size(){ return size; }

    public boolean isEmpty(){ return size==0; }

    public void add(E e){
        root = add(root,e);
    }

    private Node add(Node node,E e){
        if(node == null){
            node = new Node(e);
            size++;
            return node;
        }

        if(e.compareTo(node.e) < 0){ // e小于当前节点的值
            node.left = add(node.left,e);
        }else if(e.compareTo(node.e) > 0){ //e大于当前节点的值
            node.right = add(node.right,e);
        }

        return node;
    }

    /**
     * 二分搜索树的中序遍历,输出有序序列
     */
    public void inOrder(){
        inOrder(root);
    }

    private void inOrder(Node node){
        if(node == null){
            return ;
        }

        inOrder(node.left);
        System.out.println(node.e);
        inOrder(node.right);
    }

    /**
     * 得到该树的最小值
     * @return
     */
    public E getMin(){
        if (isEmpty()){
            throw new IllegalArgumentException("该树为空");
        }
        return getMin(root).e;
    }

    private Node getMin(Node node){
        if(node.left == null){
            return node;
        }

        return getMin(node.left);
    }

    /**
     * 得到该树的最大的元素
     * @return
     */
    public E getMax(){
        if (isEmpty()){
            throw new IllegalArgumentException("该树为空");
        }
        return getMax(root).e;
    }

    private Node getMax(Node node){
        if(node.right == null){
            return node;
        }
        return getMax(node.right);
    }

    /**
     * 删除最小值
     * @return
     */
    public E removeMin(){
        if (isEmpty()){
            throw new IllegalArgumentException("该树为空");
        }
        E min = getMin();
        root = removeMin(root);
        return min;
    }

    private Node removeMin(Node node){
        if(node.left == null){
            /*Node rightNode = node.right;
            node.right = null;
            size --;
            return rightNode;*/
            //下面为我自己写的
            node = node.right;
            size--;
            return node;
        }
        node.left = removeMin(node.left);
        //这里不要忘了返回node
        return node;
    }

    /**
     * 删除最大值
     * @return
     */
    public E removeMax(){
        if (isEmpty()){
            throw new IllegalArgumentException("该树为空");
        }
        E max = getMax();
        root = removeMax(root);
        return max;
    }

    private Node removeMax(Node node){
        if(node.right == null){
            node = node.left;
            size--;
            return node;
        }
        node.right = removeMax(node.right);
        return node;
    }

    public boolean contains(E e){
        return contains(root,e);
    }

    private boolean contains(Node node,E e){
        if(node == null){
            return false;
        }
        if(e.compareTo(node.e) < 0){
            return contains(node.left,e);
        }else if(e.compareTo(node.e) >0){
            return contains(node.right,e);
        }else {
            return true;
        }
    }

    //删除任意元素
    public void remove(E e){
        root = remove(root,e);
    }

    private Node remove(Node node, E e){
        if(node == null){
            return null;
        }
        if(e.compareTo(node.e) < 0){
            node.left = remove(node.left,e);
        }else if(e.compareTo(node.e) > 0){
            node.right = remove(node.right,e);
        }else{
            if(node.left == null){
                node = node.right;
                return node;
            }
            if(node.right == null){
                node = node.left;
                return node;
            }
            //下面就是左右子树都不为空的情况
            Node success = getMin(node.right);
            success.left = node.left;
            success.right = removeMin(node.right);
            node= node.left = node.right = null;
            return success;
        }
        return node;
    }








   /* @Override
    public String toString() {
        StringBuilder res = new StringBuilder();

    }*/
}